#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <strstream>
#include <string>

using namespace std;
#include <time.h>
#include "GL/glut.h"

#include "terrian_point.h"

#include "eyePos.h"

extern eyePos myEye;

extern GLuint theTerrainNum;

extern int frameRendered;

extern int curFPS; 

extern GLuint point_heap_callListNum;

void showScenInf()
{
	glPushAttrib(GL_ENABLE_BIT);

	glDisable(GL_LIGHTING);
	glDisable(GL_BLEND);
	glDisable( GL_TEXTURE_2D );
	glDisable(GL_DEPTH_TEST);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0.0, 800.0, 0.0, 600.0);
	glColor4f(0.0,0.0,1.0,1.0);


	char fpsbuffer[]="       \0";

	sprintf(fpsbuffer,"%d",curFPS);

	glRasterPos3f(10.0f,540.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'F');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'P');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'S');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,':');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'H');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'z');

	char eyex[18];
	sprintf(eyex,"%3.4f",myEye.geteyeatx());

	glRasterPos3f(10.0,525.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'x');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[7]);	


	char eyey[18];
	sprintf(eyey,"%3.4f",myEye.geteyeaty());

	glRasterPos3f(10.0f,510.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[7]);

	char eyez[18];
	sprintf(eyez,"%3.4f", myEye.geteyeatz());

	glRasterPos3f(10.0f,495.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'z');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[7]);

	char TANum[18];
	//sprintf(TANum,"%d", PM_->getTotalTAnum());
	sprintf(TANum,"%d", 29);

	glRasterPos3f(10.0f,480.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'T');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'A');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'n');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'u');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'m');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[7]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[8]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,TANum[9]);	


	char PTNum[18];
	//sprintf(TANum,"%d", PM_->getTotalTAnum());
	sprintf(PTNum,"%d", 29);

	glRasterPos3f(10.0f,465.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'P');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'T');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'n');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'u');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'m');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[7]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[8]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,PTNum[9]);	

	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopAttrib();
}

void drawCoordAxis()
{
	glColor3f(1.0, 0.0, 0.0);//鲜红色，x正半轴
	glBegin(GL_LINES);
	glVertex3f(1.0,0.0,0.0);
	glVertex3f(0.0,0.0,0.0);   
	glEnd();
	//glFlush();

	//glColor3f(0.5, 0.0, 0.0);
	//glBegin(GL_LINES);
	//glVertex3f(-1.0,0.0,0.0);
	//glVertex3f(0.0,0.0,0.0);   
	//glEnd();

	glColor3f(0.0, 1.0, 0.0);//绿色，y正半轴
	glBegin(GL_LINES);
	glVertex3f(0.0,1.0,0.0);
	glVertex3f(0.0,0.0,0.0);
	glEnd();

	/*glColor3f(0.0, 0.0, 0.5);
	glBegin(GL_LINES);
	glVertex3f(0.0,-1.0,0.0);
	glVertex3f(0.0,0.0,0.0);
	glEnd();*/


	glColor3f(0.0, 0.0, 1.0);//深蓝色，z正半轴
	glBegin(GL_LINES);
	glVertex3f(0.0, 0.0, 1.0);
	glVertex3f(0.0, 0.0, 0.0);
	glEnd();

	//glColor3f(0.0, 0.5, 0.0);
	//glBegin(GL_LINES);
	//glVertex3f(0.0, 0.0, -1.0);
	//glVertex3f(0.0, 0.0, 0.0);
	//glEnd();

	//glColor3f(1.0f, 0.0f, 0.0f);
	//glBegin(GL_LINES);
	//glVertex3f(myEye.geteyeatx()+0.1,myEye.geteyeaty()+0.1,myEye.geteyeatz()+0.1);
	//glVertex3f(myEye.geteyelookatx(),myEye.geteyelookaty(),myEye.geteyelookatz());
	//glEnd();

}

//根据myEye的数据重新设置模型视图矩阵
void flushDraw()
{
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer

	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();	

	gluLookAt(
		myEye.geteyeatx(),		myEye.geteyeaty(),		myEye.geteyeatz(),
		myEye.geteyelookatx(),	myEye.geteyelookaty(),	myEye.geteyelookatz(),
		myEye.getupdirx(),		myEye.getupdiry(),		myEye.getupdirz()
		);

	//glCallList(theTerrainNum);	

	//glutSwapBuffers();	

}

//将模型视图矩阵调整到一个初始默认位置
void defaultEyePos()
{

	cout<<endl<<"in func defaultEyePos"<<endl;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	myEye.returnDefalt();
	gluLookAt(
		myEye.geteyeatx(),		myEye.geteyeaty(),		myEye.geteyeatz(),
		myEye.geteyelookatx(),	myEye.geteyelookaty(),	myEye.geteyelookatz(),
		myEye.getupdirx(),		myEye.getupdiry(),		myEye.getupdirz()
		);


	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, 1.0, 0.2, 1000.0);

	glCallList(theTerrainNum);	

	glutSwapBuffers();	
}

bool ldown=false;
bool rdown=false;
int fromX, fromY;
int toX, toY;
double oldjd,oldwd;
double oldeyex,oldeyey,oldeyez;
double oldlookatx,oldlookaty,oldlookatz;

//按下鼠标的响应函数
void mouseFunc(int button, int state, int x, int y)
{
	switch(button)
	{
	case GLUT_LEFT_BUTTON:
		if(state == GLUT_DOWN)
		{
			ldown=true;
			fromX = x;
			fromY = y;
			oldjd = myEye.getJingdu();
			oldwd = myEye.getWeidu();
		}
		if(state == GLUT_UP)
		{
			ldown=false;
		}
		break;

	case GLUT_RIGHT_BUTTON:
		if(state == GLUT_DOWN)
		{
			rdown=true;
			fromX = x;
			fromY = y;

			oldeyex=myEye.geteyeatx();
			oldeyey=myEye.geteyeaty();
			oldeyez=myEye.geteyeatz();

			oldlookatx=myEye.geteyelookatx();
			oldlookaty=myEye.geteyelookaty();
			oldlookatz=myEye.geteyelookatz();
		}
		if(state == GLUT_UP)
		{
			rdown=false;
		}
		break;

	default:
		break;
	}

}


//移动鼠标的响应函数
void motionFunc(int x, int y)
{
	if(ldown)
	{
		toX=x;
		toY=y;
		myEye.routAlongSphere(oldjd+(fromX-toX)/800.0, oldwd+(fromY-toY)/800.0);
		flushDraw();
	}
	else if(rdown)
	{
		toX=x;
		toY=y;
		myEye.moveEyeLookAt(oldeyex + (fromX-toX)/400.0, 
			oldeyey + (fromY-toY)/400.0, 
			oldeyez,
			oldlookatx + (fromX-toX)/400.0,
			oldlookaty + (fromY-toY)/400.0, 
			oldlookatz);
		flushDraw();
	}

	GLfloat lightpos[]={myEye.geteyeatx(),myEye.geteyeaty(),myEye.geteyeatz(),1.0};
	glLightfv(GL_LIGHT0,GL_POSITION,lightpos);	

	GLfloat lightdirect[]={-myEye.geteyeatx(),
		-myEye.geteyeaty(),
		-myEye.geteyeatz(),
		1.0};
	glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdirect);	
}

bool drawFillMode = true;
void changePolygonMode()
{
	if(drawFillMode)
	{
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
		drawFillMode = false;
	}
	else
	{
		glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
		drawFillMode = true;
	}

}

float pointSize=1.0f;

//键盘响应函数
void keyFunc(unsigned char key, int x, int y)
{
	switch(key)
	{

	case 'M':
	case 'm':
		{
			changePolygonMode();
		}
		break;

	case 'R':
	case 'r':
		{
			defaultEyePos();
		}
		break;

	case 'n':
	case 'N':
		{
			myEye.zoomIn();
			flushDraw();
		}
		break;

	case 'F':
	case 'f':
		{
			myEye.zoomOut();
			flushDraw();
		}
		break;

	case 'l':
	case 'L':
		{
			pointSize += 0.1f;
			glPointSize(pointSize);		
			flushDraw();
		}
		break;

	case 's':
	case 'S':
		{
			pointSize -= 0.1f;
			glPointSize(pointSize);		
			flushDraw();
		}
		break;

	default:
		break;
	}
}

void display()
{
	cout<<endl<<"in func display"<<endl;

	glMatrixMode(GL_MODELVIEW);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			

	//glCallList(theTerrainNum);	

	glutSwapBuffers();	
}

//为 glutIdleFunc 注册的响应函数
void drawloop_()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer

	drawCoordAxis();	

	glCallList(point_heap_callListNum);

	showScenInf();

	glutSwapBuffers();

	++frameRendered;

	//glPopMatrix();
}
